//注意：
//所有的React内置hooks函数只能在组件或自定义hooks中使用。不能在组件外和条件判断等语句中使用。
import React, { Fragment, useEffect, useRef, useState } from 'react'
import { Button, message } from 'antd'

//自定义hooks
function useList() {
  const [list, setList] = useState([...Array(5)].map((item, index) => ({ id: index, name: `第${index+1}项` })));
  const updateList = type => {
    if(type === 'add') setList([...list, { id: list.length, name: `第${list.length+1}项`}])
    else setList(list.slice(0, -1))
  }
  return { list, updateList }
}

//子组件
function HooksChild(props) {
  const { list, updateList } = useList();

  // useEffect ---------------------------------------------------
  // useEffect是代替新生命周期的getDerivedStateFromProps(旧生命周期componentDidMount、componentDidUpdate)、componentWillUnmount生命周期函数的
  // 在useEffect有两个参数，第一个参数是函数，它在组件加载完毕，以及监听的state变化时触发，第二个参数是数组， 元素为要坚挺的state状态(若无第二个参数，默认监听全部state状态)
  // 在第一个参数的函数中，若返回一个函数，那么该函数就作为组件将要卸载，即componentWillUnmount的代替
  useEffect(() => {
    message.success('列表组件加载完毕或监听的数据发生变化了')
    return () => {
      message.success('组件将要被卸载了')
    }
  },[list])

  // const handleCilck = (type) => {
  //   return () => {reduce
      
  //   }
  // }

  //Fragment是代码片段，代替组件的根元素，并且经react编译后不会产生根节点进行包裹。
  return (
    <Fragment>
      <Button onClick={() => updateList('add')}>增加一项</Button>
      <Button onClick={() => updateList('reduce')}>删除一项</Button>
      { list.map(item => <p key={item.id}>{item.name}</p>)}
    </Fragment>
  )
}

//父组件
//Hooks解决了函数式组件没有this，就没有类式组件的state、props、ref等属性以及生命周期的声明。
export default function Hooks() {
  // useState ---------------------------------------------------
  const [baseNum, setBaseNum] = useState(1);
  const [count, setCount] = useState(0);

  const handleClick = (type) => {
    return () => {
      switch (type) {
        case 'increment_baseNum':
          setBaseNum(baseNum + 1)
          break;
        case 'decrement_baseNum':
          setBaseNum(baseNum - 1)
          break;
        case 'incrment_count':
          setCount(count + baseNum)
          break;
        case 'decrment_count':
          setCount(count - baseNum)
          break;
        default:
          break;
      }
    }
  }

  // useRef ---------------------------------------------------
  const baseNumRef = useRef()
  const sendMessageByRef = () => {
    message.success(baseNumRef.current.innerText)  //获取到元素后，根据元素节点不同，取值的字段不同
  }

  
  // const hooksChildRef = useRef()
  const [isShow, setIsShow] = useState(true)
  const handleDomMount = (type) => {
    return () => {
      if(type === 'mount') setIsShow(true)
      else setIsShow(false)
    }
  }


  return (
    <div>
        <h1>Hooks的使用: useState、useRef、useEffect</h1>
        <h3 ref={baseNumRef}>当前基数：{baseNum}</h3> 
        <h3 >当前结果：{count}</h3>
        <Button onClick={handleClick('incrment_count')}>结果加</Button>
        <Button onClick={handleClick('decrment_count')}>结果减</Button>
        &nbsp;
       
        <Button onClick={handleClick('increment_baseNum')}>基数加</Button>
        <Button onClick={handleClick('decrement_baseNum')}>基数减</Button>
        &nbsp;
        <Button onClick={sendMessageByRef}>useRef()获取Dom元素</Button>
        &nbsp;
        <Button onClick={handleDomMount('mount')}>挂载列表</Button>
        <Button onClick={handleDomMount('unmount')}>卸载列表</Button>
        { 
          // 函数式组件不能挂载ref
          isShow && <HooksChild a={111}/>
        } 
      </div>
  )
}
